const fs = require('fs')
const moment = require('moment')
const Decimal = require('decimal.js')
const chalk = require('chalk')
const _ = require('lodash')
const {
    StoreName
} = require('./../constants')
const log = console.log
let _logType = 'normal'
let _formatLogParams = null
const fnVS = (v1, v2) => {
    return v1 > v2 ? '>' : '<'
}

class LogService {
    addLog (str, str2) {
      fs.appendFileSync(
        `./log-v4/${_logType}/${moment().format('YYYYMMDDHH')}.txt`,
        `${str}${str2 ? ` ${str2}` : ''}\n`,
        'utf8',
        err => {
          if (err) {
            throw err
          }
          log(str.replace('\n', ' '), str2 || '')
        }
      )
      log(str.replace('\n', ' '), str2 || '')
    }
    print = (title, type) => {
        if (!title || !_formatLogParams) return
        const {
            bollUp,
            price,
            bollDown,
            bollMiddle,
            bollWidth,
            minBollWidth,
            bollStatus,
            lastBollUp,
            lastBollMiddle,
            lastBollDown,
            RSI,
            holdingAmount,
            openOrders,
            openOrderAmount,
            klineList,
            stochRSI,
            balance,
            xFactor,
            futurePrice,
            buildItemIndex,
            cacheBuildList,
            buildItem
        } = _formatLogParams

        let addLog = this.addLog
        _logType = type

        const kItem = klineList[klineList.length - 1]
        // let lastTotalBuildRatio
        let holdingRatio = 0
        let holdingRatioStr = ''
        if (holdingAmount) {
            holdingRatio = Decimal(holdingAmount).div(balance).toNumber()
            holdingRatioStr = Decimal(holdingRatio).mul(100).toFixed(2) + '%'
        }

        let buildAvgPrice

        // 通过openOrder的长度算出有多少单
        if (
            Array.isArray(cacheBuildList) &&
            Array.isArray(openOrders) &&
            holdingRatio
        ) {
            buildAvgPrice = buildItem.realAvgPrice
        }
        const currentPriceStr = `【${price.toFixed()}】(合约${futurePrice}${buildAvgPrice ? ` ${fnVS( futurePrice, buildAvgPrice)} 均价${buildAvgPrice}` : ''})`

        addLog('')
        addLog(`———— ${title} ————`)
        if (price > bollUp) addLog(currentPriceStr)
        addLog(`=  ${bollUp.toFixed()}  =`)
        if (price < bollUp && price > bollMiddle) addLog(currentPriceStr)
        addLog(`-  ${bollMiddle.toFixed()}  -`)
        if (price < bollMiddle && price > bollDown) addLog(currentPriceStr)
        addLog(`=  ${bollDown.toFixed()}  =`)
        if (price < bollDown) addLog(currentPriceStr)
        if (holdingAmount) addLog(
            '待成交',
            cacheBuildList.slice(buildItemIndex, buildItemIndex + 5).map(item => Number(item.buildPrice.toFixed())).join(', ')
        )
        addLog(`当前余额`, `$${Number(balance).toFixed(2)} (不算BNB)`)
        if (holdingAmount) addLog(`持有金额`, `$${Number(holdingAmount).toFixed(2)}${ holdingRatioStr ? `，(${holdingRatioStr}, ${buildItemIndex}/${cacheBuildList.length})` : ''}`)
        if (openOrderAmount) addLog(`挂单金额`, `$${Number(openOrderAmount).toFixed(2)}`)
        if (xFactor) addLog(`xFactor`, xFactor)
        addLog('交易量', `${kItem.volumn.toFixed(2)} ${fnVS(kItem.volumn, bollWidth * 1.4)} ${(bollWidth * 1.4).toFixed()}`)
        addLog(
            '布林半径',
            `${bollWidth.toFixed()} (${Decimal(lastBollUp)
                .sub(lastBollDown)
                .div(2)
                .toNumber()
                .toFixed()}) ${fnVS(bollWidth, minBollWidth)} ${minBollWidth.toFixed()}`
        )
        addLog('布林带状态', bollStatus)
        addLog('RSI', RSI)
        addLog('stochRSI', stochRSI.toFixed())
        addLog('时间', moment().format('YYYY年MM月DD日 HH点mm分ss秒'))
        addLog(`——————————————`)
          
    }
    initFormatLog (params) {
        _formatLogParams = params
    }
    addParams (params) {
        _formatLogParams = {
            ..._formatLogParams,
            ...params
        }
    }
    setState (key, str) {
        try {
            fs.writeFileSync(`./store/${key}.txt`, str)
        } catch (error) {
            return null
        }
    }
    getState (key) {
        try {
            const data = fs.readFileSync(`./store/${key}.txt`, 'utf-8')
            return data ? data : null
        } catch (error) {
            return null
        }
    }
    setJson (key, data) {
        try {
            fs.writeFileSync(`./store/${key}.json`, JSON.stringify(data, null, 4))
        } catch (error) {
            return null
        }
    }
    getJson (key) {
        try {
            const data = fs.readFileSync(`./store/${key}.json`)
            return data ? JSON.parse(data) : null
        } catch (error) {
            return null
        }
    }
    clear () {
        this.setState(StoreName.HOLDING_ORDER_BOLL_STATUS, '')
        this.setState(StoreName.HOLDING_ORDER_BTC_QUANTITY, '')
        this.setState(StoreName.HOLDING_ORDER_DIRECTION, '')
        this.setState(StoreName.OPEN_ORDER_TIMESTAMP, '')
        this.setState(StoreName.PROTECT_ORDER_INDEX, '')
    }
}

module.exports = new LogService()
